// 版权2019 etcd作者
// 
// 根据Apache许可证2.0版（以下简称“许可证”）获得许可；
// 除非遵守许可证，否则不得使用此文件。
// 您可以通过
// 
// www.apache.org/licenses/LICENSE-2.0 
// 
// 除非适用法律要求或书面同意，否则根据许可证分发的软件
// 按“原样”分发，
// 无任何明示或暗示的保证或条件。
// 请参阅许可证，了解管理许可的特定语言和
// 许可证下的限制。

package quorum

// JointConfig是由两组（可能重叠）
// 多数配置组成的配置。决定需要两个多数的支持。
type JointConfig [2]MajorityConfig

func (c JointConfig) String() string {
	if len(c[1]) > 0 {
		return c[0].String() + "&&" + c[1].String()
	}
	return c[0].String()
}

// IDs返回一个新初始化的映射，该映射表示联合配置中出现
// 的投票者集。
func (c JointConfig) IDs() map[uint64]struct{} {
	m := map[uint64]struct{}{}
	for _, cc := range c {
		for id := range cc {
			m[id] = struct{}{}
		}
	}
	return m
}

// descripe返回给定lookuper的提交索引的（多行）表示形式。
func (c JointConfig) Describe(l AckedIndexer) string {
	return MajorityConfig(c.IDs()).Describe(l)
}

// CommittedIndex返回给定联合
// quorum的最大提交索引。如果一个指数在两个组成部分
// /多数中都被提交，则该指数是共同提交的。
func (c JointConfig) CommittedIndex(l AckedIndexer) Index {
	idx0 := c[0].CommittedIndex(l)
	idx1 := c[1].CommittedIndex(l)
	if idx0 < idx1 {
		return idx0
	}
	return idx1
}

// VoteResult获取选民到是/否（真/假）投票的映射，并返回
// 一个结果，指示投票是待定、失败还是获胜。联合法定人数
// 要求两个多数票都投赞成票。
func (c JointConfig) VoteResult(votes map[uint64]bool) VoteResult {
	r1 := c[0].VoteResult(votes)
	r2 := c[1].VoteResult(votes)

	if r1 == r2 {
		// 如果他们同意，返回约定状态。
		return r1
	}
	if r1 == VoteLost || r2 == VoteLost {
		// 如果任一配置丢失，则丢失是唯一可能的结果。
		return VoteLost
	}
	// 一方获胜，另一方悬而未决，因此整个结果都是未知的。
	return VotePending
}
